Code coverage report for src/parser.js

Statements: 75.79% (191 / 252)      Branches: 56.64% (64 / 113)      Functions: 97.06% (33 / 34)      Lines: 75.42% (178 / 236)      Ignored: none     

All files » src/ » parser.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 4041     1   1   54   1   1 1   1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1     1   1 1 27   27 27     1 27   27     1     1   1 1 27   27 27 27     1 27     27       27 27       27 27   27       27         27     1 27   27                             27     1 46     46                       46     1 46     46                           46     1 46   46       46     1 46   46       46     1 46   46 46   46   46   46     46         1 46   46 46   46   46   46     46         1 46   46 46   46     46         1 46   46 46   46   46     46         1 46   46   46     46       1 46   46 58 3   3   3         3   55 9 9 9 46         46         1 46       46   46   46   46 1 1 1 45 2 43 33 10 10 10 10               1 33   33   33 32     1 1 1     1 2     2   2 2     4 4   4 4   4       2   2     1 2   2 2 6       2     1 1436 20 20     1416     1 19 19           1 89     1           1     1830       1     1        
System.register(['./lexer', './ast'], function (_export) {
  'use strict';
 
  var Lexer, Token, Expression, ArrayOfExpression, Chain, ValueConverter, Assign, Conditional, AccessScope, AccessMember, AccessKeyed, CallScope, CallFunction, CallMember, PrefixNot, Binary, LiteralPrimitive, LiteralArray, LiteralObject, LiteralString, EOF, Parser, ParserImplementation;
 
  var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; Iif ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { Eif (protoProps) defineProperties(Constructor.prototype, protoProps); Iif (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
 
  function _classCallCheck(instance, Constructor) { Iif (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
 
  return {
    setters: [function (_lexer) {
      Lexer = _lexer.Lexer;
      Token = _lexer.Token;
    }, function (_ast) {
      Expression = _ast.Expression;
      ArrayOfExpression = _ast.ArrayOfExpression;
      Chain = _ast.Chain;
      ValueConverter = _ast.ValueConverter;
      Assign = _ast.Assign;
      Conditional = _ast.Conditional;
      AccessScope = _ast.AccessScope;
      AccessMember = _ast.AccessMember;
      AccessKeyed = _ast.AccessKeyed;
      CallScope = _ast.CallScope;
      CallFunction = _ast.CallFunction;
      CallMember = _ast.CallMember;
      PrefixNot = _ast.PrefixNot;
      Binary = _ast.Binary;
      LiteralPrimitive = _ast.LiteralPrimitive;
      LiteralArray = _ast.LiteralArray;
      LiteralObject = _ast.LiteralObject;
      LiteralString = _ast.LiteralString;
    }],
    execute: function () {
      EOF = new Token(-1, null);
 
      Parser = (function () {
        function Parser() {
          _classCallCheck(this, Parser);
 
          this.cache = {};
          this.lexer = new Lexer();
        }
 
        Parser.prototype.parse = function parse(input) {
          input = input || '';
 
          return this.cache[input] || (this.cache[input] = new ParserImplementation(this.lexer, input).parseChain());
        };
 
        return Parser;
      })();
 
      _export('Parser', Parser);
 
      ParserImplementation = (function () {
        function ParserImplementation(lexer, input) {
          _classCallCheck(this, ParserImplementation);
 
          this.index = 0;
          this.input = input;
          this.tokens = lexer.lex(input);
        }
 
        ParserImplementation.prototype.parseChain = function parseChain() {
          var isChain = false,
              expressions = [];
 
          while (this.optional(';')) {
            isChain = true;
          }
 
          while (this.index < this.tokens.length) {
            Iif (this.peek.text === ')' || this.peek.text === '}' || this.peek.text === ']') {
              this.error('Unconsumed token ' + this.peek.text);
            }
 
            var expr = this.parseValueConverter();
            expressions.push(expr);
 
            while (this.optional(';')) {
              isChain = true;
            }
 
            Iif (isChain && expr instanceof ValueConverter) {
              this.error('cannot have a value converter in a chain');
            }
          }
 
          return expressions.length === 1 ? expressions[0] : new Chain(expressions);
        };
 
        ParserImplementation.prototype.parseValueConverter = function parseValueConverter() {
          var result = this.parseExpression();
 
          while (this.optional('|')) {
            var name = this.peek.text,
                // TODO(kasperl): Restrict to identifier?
            args = [];
 
            this.advance();
 
            while (this.optional(':')) {
              // TODO(kasperl): Is this really supposed to be expressions?
              args.push(this.parseExpression());
            }
 
            result = new ValueConverter(result, name, args, [result].concat(args));
          }
 
          return result;
        };
 
        ParserImplementation.prototype.parseExpression = function parseExpression() {
          var start = this.peek.index,
              result = this.parseConditional();
 
          while (this.peek.text === '=') {
            if (!result.isAssignable) {
              var end = this.index < this.tokens.length ? this.peek.index : this.input.length;
              var expression = this.input.substring(start, end);
 
              this.error('Expression ' + expression + ' is not assignable');
            }
 
            this.expect('=');
            result = new Assign(result, this.parseConditional());
          }
 
          return result;
        };
 
        ParserImplementation.prototype.parseConditional = function parseConditional() {
          var start = this.peek.index,
              result = this.parseLogicalOr();
 
          Iif (this.optional('?')) {
            var yes = this.parseExpression();
 
            if (!this.optional(':')) {
              var end = this.index < this.tokens.length ? this.peek.index : this.input.length;
              var expression = this.input.substring(start, end);
 
              this.error('Conditional expression ' + expression + ' requires all 3 expressions');
            }
 
            var no = this.parseExpression();
            result = new Conditional(result, yes, no);
          }
 
          return result;
        };
 
        ParserImplementation.prototype.parseLogicalOr = function parseLogicalOr() {
          var result = this.parseLogicalAnd();
 
          while (this.optional('||')) {
            result = new Binary('||', result, this.parseLogicalAnd());
          }
 
          return result;
        };
 
        ParserImplementation.prototype.parseLogicalAnd = function parseLogicalAnd() {
          var result = this.parseEquality();
 
          while (this.optional('&&')) {
            result = new Binary('&&', result, this.parseEquality());
          }
 
          return result;
        };
 
        ParserImplementation.prototype.parseEquality = function parseEquality() {
          var result = this.parseRelational();
 
          while (true) {
            Iif (this.optional('==')) {
              result = new Binary('==', result, this.parseRelational());
            } else Iif (this.optional('!=')) {
              result = new Binary('!=', result, this.parseRelational());
            } else Iif (this.optional('===')) {
              result = new Binary('===', result, this.parseRelational());
            } else Iif (this.optional('!==')) {
              result = new Binary('!==', result, this.parseRelational());
            } else {
              return result;
            }
          }
        };
 
        ParserImplementation.prototype.parseRelational = function parseRelational() {
          var result = this.parseAdditive();
 
          while (true) {
            Iif (this.optional('<')) {
              result = new Binary('<', result, this.parseAdditive());
            } else Iif (this.optional('>')) {
              result = new Binary('>', result, this.parseAdditive());
            } else Iif (this.optional('<=')) {
              result = new Binary('<=', result, this.parseAdditive());
            } else Iif (this.optional('>=')) {
              result = new Binary('>=', result, this.parseAdditive());
            } else {
              return result;
            }
          }
        };
 
        ParserImplementation.prototype.parseAdditive = function parseAdditive() {
          var result = this.parseMultiplicative();
 
          while (true) {
            Iif (this.optional('+')) {
              result = new Binary('+', result, this.parseMultiplicative());
            } else Iif (this.optional('-')) {
              result = new Binary('-', result, this.parseMultiplicative());
            } else {
              return result;
            }
          }
        };
 
        ParserImplementation.prototype.parseMultiplicative = function parseMultiplicative() {
          var result = this.parsePrefix();
 
          while (true) {
            Iif (this.optional('*')) {
              result = new Binary('*', result, this.parsePrefix());
            } else Iif (this.optional('%')) {
              result = new Binary('%', result, this.parsePrefix());
            } else Iif (this.optional('/')) {
              result = new Binary('/', result, this.parsePrefix());
            } else {
              return result;
            }
          }
        };
 
        ParserImplementation.prototype.parsePrefix = function parsePrefix() {
          Iif (this.optional('+')) {
            return this.parsePrefix(); // TODO(kasperl): This is different than the original parser.
          } else Iif (this.optional('-')) {
            return new Binary('-', new LiteralPrimitive(0), this.parsePrefix());
          } else Iif (this.optional('!')) {
            return new PrefixNot('!', this.parsePrefix());
          } else {
            return this.parseAccessOrCallMember();
          }
        };
 
        ParserImplementation.prototype.parseAccessOrCallMember = function parseAccessOrCallMember() {
          var result = this.parsePrimary();
 
          while (true) {
            if (this.optional('.')) {
              var name = this.peek.text; // TODO(kasperl): Check that this is an identifier. Are keywords okay?
 
              this.advance();
 
              Iif (this.optional('(')) {
                var args = this.parseExpressionList(')');
                this.expect(')');
                result = new CallMember(result, name, args);
              } else {
                result = new AccessMember(result, name);
              }
            } else if (this.optional('[')) {
              var key = this.parseExpression();
              this.expect(']');
              result = new AccessKeyed(result, key);
            } else Iif (this.optional('(')) {
              var args = this.parseExpressionList(')');
              this.expect(')');
              result = new CallFunction(result, args);
            } else {
              return result;
            }
          }
        };
 
        ParserImplementation.prototype.parsePrimary = function parsePrimary() {
          Iif (this.optional('(')) {
            var result = this.parseExpression();
            this.expect(')');
            return result;
          } else Iif (this.optional('null') || this.optional('undefined')) {
            return new LiteralPrimitive(null);
          } else Iif (this.optional('true')) {
            return new LiteralPrimitive(true);
          } else Iif (this.optional('false')) {
            return new LiteralPrimitive(false);
          } else if (this.optional('[')) {
            var elements = this.parseExpressionList(']');
            this.expect(']');
            return new LiteralArray(elements);
          } else if (this.peek.text == '{') {
            return this.parseObject();
          } else if (this.peek.key != null) {
            return this.parseAccessOrCallScope();
          } else Eif (this.peek.value != null) {
            var value = this.peek.value;
            this.advance();
            return isNaN(value) ? new LiteralString(value) : new LiteralPrimitive(value);
          } else if (this.index >= this.tokens.length) {
            throw new Error('Unexpected end of expression: ' + this.input);
          } else {
            this.error('Unexpected token ' + this.peek.text);
          }
        };
 
        ParserImplementation.prototype.parseAccessOrCallScope = function parseAccessOrCallScope() {
          var name = this.peek.key;
 
          this.advance();
 
          if (!this.optional('(')) {
            return new AccessScope(name);
          }
 
          var args = this.parseExpressionList(')');
          this.expect(')');
          return new CallScope(name, args);
        };
 
        ParserImplementation.prototype.parseObject = function parseObject() {
          var keys = [],
              values = [];
 
          this.expect('{');
 
          Eif (this.peek.text !== '}') {
            do {
              // TODO(kasperl): Stricter checking. Only allow identifiers
              // and strings as keys. Maybe also keywords?
              var value = this.peek.value;
              keys.push(typeof value === 'string' ? value : this.peek.text);
 
              this.advance();
              this.expect(':');
 
              values.push(this.parseExpression());
            } while (this.optional(','));
          }
 
          this.expect('}');
 
          return new LiteralObject(keys, values);
        };
 
        ParserImplementation.prototype.parseExpressionList = function parseExpressionList(terminator) {
          var result = [];
 
          Eif (this.peek.text != terminator) {
            do {
              result.push(this.parseExpression());
            } while (this.optional(','));
          }
 
          return result;
        };
 
        ParserImplementation.prototype.optional = function optional(text) {
          if (this.peek.text === text) {
            this.advance();
            return true;
          }
 
          return false;
        };
 
        ParserImplementation.prototype.expect = function expect(text) {
          Eif (this.peek.text === text) {
            this.advance();
          } else {
            this.error('Missing expected ' + text);
          }
        };
 
        ParserImplementation.prototype.advance = function advance() {
          this.index++;
        };
 
        ParserImplementation.prototype.error = function error(message) {
          var location = this.index < this.tokens.length ? 'at column ' + (this.tokens[this.index].index + 1) + ' in' : 'at the end of the expression';
 
          throw new Error('Parser Error: ' + message + ' ' + location + ' [' + this.input + ']');
        };
 
        _createClass(ParserImplementation, [{
          key: 'peek',
          get: function () {
            return this.index < this.tokens.length ? this.tokens[this.index] : EOF;
          }
        }]);
 
        return ParserImplementation;
      })();
 
      _export('ParserImplementation', ParserImplementation);
    }
  };
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9FaXNlbmJlcmdFZmZlY3QvRG9jdW1lbnRzL0dpdEh1Yi9UaGUgRHVyYW5kYWwgUHJvamVjdC9hdXJlbGlhL2JpbmRpbmcvc3JjL3BhcnNlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7NlBBTUksR0FBRyxFQUVNLE1BQU0sRUFjTixvQkFBb0I7Ozs7Ozs7O3FCQXRCekIsS0FBSztxQkFBQyxLQUFLOzt3QkFDWCxVQUFVOytCQUFFLGlCQUFpQjttQkFBRSxLQUFLOzRCQUFFLGNBQWM7b0JBQUUsTUFBTTt5QkFDNUQsV0FBVzt5QkFBRSxXQUFXOzBCQUFFLFlBQVk7eUJBQUUsV0FBVzt1QkFDbkQsU0FBUzswQkFBRSxZQUFZO3dCQUFFLFVBQVU7dUJBQUUsU0FBUztvQkFDOUMsTUFBTTs4QkFBRSxnQkFBZ0I7MEJBQUUsWUFBWTsyQkFBRSxhQUFhOzJCQUFFLGFBQWE7OztBQUV4RSxTQUFHLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDOztBQUVoQixZQUFNO0FBQ04saUJBREEsTUFBTSxHQUNKO2dDQURGLE1BQU07O0FBRWYsY0FBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7QUFDaEIsY0FBSSxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1NBQzFCOztBQUpVLGNBQU0sV0FNakIsS0FBSyxHQUFBLGVBQUMsS0FBSyxFQUFFO0FBQ1gsZUFBSyxHQUFHLEtBQUssSUFBSSxFQUFFLENBQUM7O0FBRXBCLGlCQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQ2xCLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFBLEFBQUMsQ0FBQztTQUNyRjs7ZUFYVSxNQUFNOzs7d0JBQU4sTUFBTTs7QUFjTiwwQkFBb0I7QUFDcEIsaUJBREEsb0JB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Y0FBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLEVBQUU7QUFDM0IsZ0JBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztXQUNoQixNQUFNO0FBQ0wsZ0JBQUksQ0FBQyxLQUFLLHVCQUFxQixJQUFJLENBQUcsQ0FBQztXQUN4QztTQUNGOztBQW5VVSw0QkFBb0IsV0FxVS9CLE9BQU8sR0FBQSxtQkFBRTtBQUNQLGNBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztTQUNkOztBQXZVVSw0QkFBb0IsV0F5VS9CLEtBQUssR0FBQSxlQUFDLE9BQU8sRUFBRTtBQUNiLGNBQUksUUFBUSxHQUFHLEFBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sbUJBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUEseUNBQ2hCLENBQUM7O0FBRXJDLGdCQUFNLElBQUksS0FBSyxvQkFBa0IsT0FBTyxTQUFJLFFBQVEsVUFBSyxJQUFJLENBQUMsS0FBSyxPQUFJLENBQUM7U0FDekU7O3FCQS9VVSxvQkFBb0I7O2VBT3ZCLFlBQUc7QUFDVCxtQkFBTyxBQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDO1dBQzFFOzs7ZUFUVSxvQkFBb0I7OztzQ0FBcEIsb0JBQW9CIiwiZmlsZSI6Ii9Vc2Vycy9FaXNlbmJlcmdFZmZlY3QvRG9jdW1lbnRzL0dpdEh1Yi9UaGUgRHVyYW5kYWwgUHJvamVjdC9hdXJlbGlhL2JpbmRpbmcvc3JjL3BhcnNlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TGV4ZXIsVG9rZW59IGZyb20gJy4vbGV4ZXInO1xuaW1wb3J0IHtFeHByZXNzaW9uLCBBcnJheU9mRXhwcmVzc2lvbiwgQ2hhaW4sIFZhbHVlQ29udmVydGVyLCBBc3NpZ24sXG4gICAgICAgIENvbmRpdGlvbmFsLCBBY2Nlc3NTY29wZSwgQWNjZXNzTWVtYmVyLCBBY2Nlc3NLZXllZCxcbiAgICAgICAgQ2FsbFNjb3BlLCBDYWxsRnVuY3Rpb24sIENhbGxNZW1iZXIsIFByZWZpeE5vdCxcbiAgICAgICAgQmluYXJ5LCBMaXRlcmFsUHJpbWl0aXZlLCBMaXRlcmFsQXJyYXksIExpdGVyYWxPYmplY3QsIExpdGVyYWxTdHJpbmd9IGZyb20gJy4vYXN0JztcblxudmFyIEVPRiA9IG5ldyBUb2tlbigtMSwgbnVsbCk7XG5cbmV4cG9ydCBjbGFzcyBQYXJzZXIge1xuICBjb25zdHJ1Y3Rvcigpe1xuICAgIHRoaXMuY2FjaGUgPSB7fTtcbiAgICB0aGlzLmxleGVyID0gbmV3IExleGVyKCk7XG4gIH1cblxuICBwYXJzZShpbnB1dCkge1xuICAgIGlucHV0ID0gaW5wdXQgfHwgJyc7XG5cbiAgICByZXR1cm4gdGhpcy5jYWNoZVtpbnB1dF1cbiAgICAgIHx8ICh0aGlzLmNhY2hlW2lucHV0XSA9IG5ldyBQYXJzZXJJbXBsZW1lbnRhdGlvbih0aGlzLmxleGVyLCBpbnB1dCkucGFyc2VDaGFpbigpKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFyc2VySW1wbGVtZW50YXRpb24ge1xuICBjb25zdHJ1Y3RvcihsZXhlciwgaW5wdXQpIHtcbiAgICB0aGlzLmluZGV4ID0gMDtcbiAgICB0aGlzLmlucHV0ID0gaW5wdXQ7XG4gICAgdGhpcy50b2tlbnMgPSBsZXhlci5sZXgoaW5wdXQpO1xuICB9XG5cbiAgZ2V0IHBlZWsoKSB7XG4gICAgcmV0dXJuICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSA/IHRoaXMudG9rZW5zW3RoaXMuaW5kZXhdIDogRU9GO1xuICB9XG5cbiAgcGFyc2VDaGFpbigpIHtcbiAgICB2YXIgaXNDaGFpbiA9IGZhbHNlLFxuICAgICAgICBleHByZXNzaW9ucyA9IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMub3B0aW9uYWwoJzsnKSkge1xuICAgICAgaXNDaGFpbiA9IHRydWU7XG4gICAgfVxuXG4gICAgd2hpbGUgKHRoaXMuaW5kZXggPCB0aGlzLnRva2Vucy5sZW5ndGgpIHtcbiAgICAgIGlmICh0aGlzLnBlZWsudGV4dCA9PT0gJyknIHx8IHRoaXMucGVlay50ZXh0ID09PSAnfScgfHwgdGhpcy5wZWVrLnRleHQgPT09ICddJykge1xuICAgICAgICB0aGlzLmVycm9yKGBVbmNvbnN1bWVkIHRva2VuICR7dGhpcy5wZWVrLnRleHR9YCk7XG4gICAgICB9XG5cbiAgICAgIHZhciBleHByID0gdGhpcy5wYXJzZVZhbHVlQ29udmVydGVyKCk7XG4gICAgICBleHByZXNzaW9ucy5wdXNoKGV4cHIpO1xuXG4gICAgICB3aGlsZSAodGhpcy5vcHRpb25hbCgnOycpKSB7XG4gICAgICAgIGlzQ2hhaW4gPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNDaGFpbiAmJiBleHByIGluc3RhbmNlb2YgVmFsdWVDb252ZXJ0ZXIpIHtcbiAgICAgICAgdGhpcy5lcnJvcignY2Fubm90IGhhdmUgYSB2YWx1ZSBjb252ZXJ0ZXIgaW4gYSBjaGFpbicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAoZXhwcmVzc2lvbnMubGVuZ3RoID09PSAxKSA/IGV4cHJlc3Npb25zWzBdIDogbmV3IENoYWluKGV4cHJlc3Npb25zKTtcbiAgfVxuXG4gIHBhcnNlVmFsdWVDb252ZXJ0ZXIoKSB7XG4gICAgdmFyIHJlc3VsdCA9IHRoaXMucGFyc2VFeHByZXNzaW9uKCk7XG5cbiAgICB3aGlsZSAodGhpcy5vcHRpb25hbCgnfCcpKSB7XG4gICAgICB2YXIgbmFtZSA9IHRoaXMucGVlay50ZXh0LCAvLyBUT0RPKGthc3BlcmwpOiBSZXN0cmljdCB0byBpZGVudGlmaWVyP1xuICAgICAgICAgIGFyZ3MgPSBbXTtcblxuICAgICAgdGhpcy5hZHZhbmNlKCk7XG5cbiAgICAgIHdoaWxlICh0aGlzLm9wdGlvbmFsKCc6JykpIHtcbiAgICAgICAgLy8gVE9ETyhrYXNwZXJsKTogSXMgdGhpcyByZWFsbHkgc3VwcG9zZWQgdG8gYmUgZXhwcmVzc2lvbnM/XG4gICAgICAgIGFyZ3MucHVzaCh0aGlzLnBhcnNlRXhwcmVzc2lvbigpKTtcbiAgICAgIH1cblxuICAgICAgcmVzdWx0ID0gbmV3IFZhbHVlQ29udmVydGVyKHJlc3VsdCwgbmFtZSwgYXJncywgW3Jlc3VsdF0uY29uY2F0KGFyZ3MpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VFeHByZXNzaW9uKCkge1xuICAgIHZhciBzdGFydCA9IHRoaXMucGVlay5pbmRleCxcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5wYXJzZUNvbmRpdGlvbmFsKCk7XG5cbiAgICB3aGlsZSAodGhpcy5wZWVrLnRleHQgPT09ICc9Jykge1xuICAgICAgaWYgKCFyZXN1bHQuaXNBc3NpZ25hYmxlKSB7XG4gICAgICAgIHZhciBlbmQgPSAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCkgPyB0aGlzLnBlZWsuaW5kZXggOiB0aGlzLmlucHV0Lmxlbmd0aDtcbiAgICAgICAgdmFyIGV4cHJlc3Npb24gPSB0aGlzLmlucHV0LnN1YnN0cmluZyhzdGFydCwgZW5kKTtcblxuICAgICAgICB0aGlzLmVycm9yKGBFeHByZXNzaW9uICR7ZXhwcmVzc2lvbn0gaXMgbm90IGFzc2lnbmFibGVgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5leHBlY3QoJz0nKTtcbiAgICAgIHJlc3VsdCA9IG5ldyBBc3NpZ24ocmVzdWx0LCB0aGlzLnBhcnNlQ29uZGl0aW9uYWwoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHBhcnNlQ29uZGl0aW9uYWwoKSB7XG4gICAgdmFyIHN0YXJ0ID0gdGhpcy5wZWVrLmluZGV4LFxuICAgICAgICByZXN1bHQgPSB0aGlzLnBhcnNlTG9naWNhbE9yKCk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25hbCgnPycpKSB7XG4gICAgICB2YXIgeWVzID0gdGhpcy5wYXJzZUV4cHJlc3Npb24oKTtcblxuICAgICAgaWYgKCF0aGlzLm9wdGlvbmFsKCc6JykpIHtcbiAgICAgICAgdmFyIGVuZCA9ICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSA/IHRoaXMucGVlay5pbmRleCA6IHRoaXMuaW5wdXQubGVuZ3RoO1xuICAgICAgICB2YXIgZXhwcmVzc2lvbiA9IHRoaXMuaW5wdXQuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpO1xuXG4gICAgICAgIHRoaXMuZXJyb3IoYENvbmRpdGlvbmFsIGV4cHJlc3Npb24gJHtleHByZXNzaW9ufSByZXF1aXJlcyBhbGwgMyBleHByZXNzaW9uc2ApO1xuICAgICAgfVxuXG4gICAgICB2YXIgbm8gPSB0aGlzLnBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgcmVzdWx0ID0gbmV3IENvbmRpdGlvbmFsKHJlc3VsdCwgeWVzLCBubyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHBhcnNlTG9naWNhbE9yKCkge1xuICAgIHZhciByZXN1bHQgPSB0aGlzLnBhcnNlTG9naWNhbEFuZCgpO1xuXG4gICAgd2hpbGUgKHRoaXMub3B0aW9uYWwoJ3x8JykpIHtcbiAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkoJ3x8JywgcmVzdWx0LCB0aGlzLnBhcnNlTG9naWNhbEFuZCgpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VMb2dpY2FsQW5kKCkge1xuICAgIHZhciByZXN1bHQgPSB0aGlzLnBhcnNlRXF1YWxpdHkoKTtcblxuICAgIHdoaWxlICh0aGlzLm9wdGlvbmFsKCcmJicpKSB7XG4gICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KCcmJicsIHJlc3VsdCwgdGhpcy5wYXJzZUVxdWFsaXR5KCkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwYXJzZUVxdWFsaXR5KCkge1xuICAgIHZhciByZXN1bHQgPSB0aGlzLnBhcnNlUmVsYXRpb25hbCgpO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmICh0aGlzLm9wdGlvbmFsKCc9PScpKSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkoJz09JywgcmVzdWx0LCB0aGlzLnBhcnNlUmVsYXRpb25hbCgpKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25hbCgnIT0nKSkge1xuICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KCchPScsIHJlc3VsdCwgdGhpcy5wYXJzZVJlbGF0aW9uYWwoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWwoJz09PScpKSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkoJz09PScsIHJlc3VsdCwgdGhpcy5wYXJzZVJlbGF0aW9uYWwoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWwoJyE9PScpKSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkoJyE9PScsIHJlc3VsdCwgdGhpcy5wYXJzZVJlbGF0aW9uYWwoKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHBhcnNlUmVsYXRpb25hbCgpIHtcbiAgICB2YXIgcmVzdWx0ID0gdGhpcy5wYXJzZUFkZGl0aXZlKCk7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKHRoaXMub3B0aW9uYWwoJzwnKSkge1xuICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KCc8JywgcmVzdWx0LCB0aGlzLnBhcnNlQWRkaXRpdmUoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWwoJz4nKSkge1xuICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KCc+JywgcmVzdWx0LCB0aGlzLnBhcnNlQWRkaXRpdmUoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWwoJzw9JykpIHtcbiAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSgnPD0nLCByZXN1bHQsIHRoaXMucGFyc2VBZGRpdGl2ZSgpKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25hbCgnPj0nKSkge1xuICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KCc+PScsIHJlc3VsdCwgdGhpcy5wYXJzZUFkZGl0aXZlKCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYXJzZUFkZGl0aXZlKCkge1xuICAgIHZhciByZXN1bHQgPSB0aGlzLnBhcnNlTXVsdGlwbGljYXRpdmUoKTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25hbCgnKycpKSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkoJysnLCByZXN1bHQsIHRoaXMucGFyc2VNdWx0aXBsaWNhdGl2ZSgpKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25hbCgnLScpKSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkoJy0nLCByZXN1bHQsIHRoaXMucGFyc2VNdWx0aXBsaWNhdGl2ZSgpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcGFyc2VNdWx0aXBsaWNhdGl2ZSgpIHtcbiAgICB2YXIgcmVzdWx0ID0gdGhpcy5wYXJzZVByZWZpeCgpO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmICh0aGlzLm9wdGlvbmFsKCcqJykpIHtcbiAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSgnKicsIHJlc3VsdCwgdGhpcy5wYXJzZVByZWZpeCgpKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25hbCgnJScpKSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkoJyUnLCByZXN1bHQsIHRoaXMucGFyc2VQcmVmaXgoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWwoJy8nKSkge1xuICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KCcvJywgcmVzdWx0LCB0aGlzLnBhcnNlUHJlZml4KCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYXJzZVByZWZpeCgpIHtcbiAgICBpZiAodGhpcy5vcHRpb25hbCgnKycpKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXJzZVByZWZpeCgpOyAvLyBUT0RPKGthc3BlcmwpOiBUaGlzIGlzIGRpZmZlcmVudCB0aGFuIHRoZSBvcmlnaW5hbCBwYXJzZXIuXG4gICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbmFsKCctJykpIHtcbiAgICAgIHJldHVybiBuZXcgQmluYXJ5KCctJywgbmV3IExpdGVyYWxQcmltaXRpdmUoMCksIHRoaXMucGFyc2VQcmVmaXgoKSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbmFsKCchJykpIHtcbiAgICAgIHJldHVybiBuZXcgUHJlZml4Tm90KCchJywgdGhpcy5wYXJzZVByZWZpeCgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VBY2Nlc3NPckNhbGxNZW1iZXIoKTtcbiAgICB9XG4gIH1cblxuICBwYXJzZUFjY2Vzc09yQ2FsbE1lbWJlcigpIHtcbiAgICB2YXIgcmVzdWx0ID0gdGhpcy5wYXJzZVByaW1hcnkoKTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25hbCgnLicpKSB7XG4gICAgICAgIHZhciBuYW1lID0gdGhpcy5wZWVrLnRleHQ7IC8vIFRPRE8oa2FzcGVybCk6IENoZWNrIHRoYXQgdGhpcyBpcyBhbiBpZGVudGlmaWVyLiBBcmUga2V5d29yZHMgb2theT9cblxuICAgICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgICBpZiAodGhpcy5vcHRpb25hbCgnKCcpKSB7XG4gICAgICAgICAgdmFyIGFyZ3MgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbkxpc3QoJyknKTtcbiAgICAgICAgICB0aGlzLmV4cGVjdCgnKScpO1xuICAgICAgICAgIHJlc3VsdCA9IG5ldyBDYWxsTWVtYmVyKHJlc3VsdCwgbmFtZSwgYXJncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0ID0gbmV3IEFjY2Vzc01lbWJlcihyZXN1bHQsIG5hbWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWwoJ1snKSkge1xuICAgICAgICB2YXIga2V5ID0gdGhpcy5wYXJzZUV4cHJlc3Npb24oKTtcbiAgICAgICAgdGhpcy5leHBlY3QoJ10nKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IEFjY2Vzc0tleWVkKHJlc3VsdCwga2V5KTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25hbCgnKCcpKSB7XG4gICAgICAgIHZhciBhcmdzID0gdGhpcy5wYXJzZUV4cHJlc3Npb25MaXN0KCcpJyk7XG4gICAgICAgIHRoaXMuZXhwZWN0KCcpJyk7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBDYWxsRnVuY3Rpb24ocmVzdWx0LCBhcmdzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcGFyc2VQcmltYXJ5KCkge1xuICAgIGlmICh0aGlzLm9wdGlvbmFsKCcoJykpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbigpO1xuICAgICAgdGhpcy5leHBlY3QoJyknKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbmFsKCdudWxsJykgfHwgdGhpcy5vcHRpb25hbCgndW5kZWZpbmVkJykpIHtcbiAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZShudWxsKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWwoJ3RydWUnKSkge1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRydWUpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25hbCgnZmFsc2UnKSkge1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKGZhbHNlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9uYWwoJ1snKSkge1xuICAgICAgdmFyIGVsZW1lbnRzID0gdGhpcy5wYXJzZUV4cHJlc3Npb25MaXN0KCddJyk7XG4gICAgICB0aGlzLmV4cGVjdCgnXScpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsQXJyYXkoZWxlbWVudHMpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5wZWVrLnRleHQgPT0gJ3snKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXJzZU9iamVjdCgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5wZWVrLmtleSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXJzZUFjY2Vzc09yQ2FsbFNjb3BlKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnBlZWsudmFsdWUgIT0gbnVsbCkge1xuICAgICAgdmFyIHZhbHVlID0gdGhpcy5wZWVrLnZhbHVlO1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gaXNOYU4odmFsdWUpID8gbmV3IExpdGVyYWxTdHJpbmcodmFsdWUpIDogbmV3IExpdGVyYWxQcmltaXRpdmUodmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleCA+PSB0aGlzLnRva2Vucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBlbmQgb2YgZXhwcmVzc2lvbjogJHt0aGlzLmlucHV0fWApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVycm9yKGBVbmV4cGVjdGVkIHRva2VuICR7dGhpcy5wZWVrLnRleHR9YCk7XG4gICAgfVxuICB9XG5cbiAgcGFyc2VBY2Nlc3NPckNhbGxTY29wZSgpICB7XG4gICAgdmFyIG5hbWUgPSB0aGlzLnBlZWsua2V5O1xuXG4gICAgdGhpcy5hZHZhbmNlKCk7XG5cbiAgICBpZiAoIXRoaXMub3B0aW9uYWwoJygnKSkge1xuICAgICAgcmV0dXJuIG5ldyBBY2Nlc3NTY29wZShuYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgYXJncyA9IHRoaXMucGFyc2VFeHByZXNzaW9uTGlzdCgnKScpO1xuICAgIHRoaXMuZXhwZWN0KCcpJyk7XG4gICAgcmV0dXJuIG5ldyBDYWxsU2NvcGUobmFtZSwgYXJncyk7XG4gIH1cblxuICBwYXJzZU9iamVjdCgpIHtcbiAgICB2YXIga2V5cyA9IFtdLFxuICAgICAgICB2YWx1ZXMgPSBbXTtcblxuICAgIHRoaXMuZXhwZWN0KCd7Jyk7XG5cbiAgICBpZiAodGhpcy5wZWVrLnRleHQgIT09ICd9Jykge1xuICAgICAgZG8ge1xuICAgICAgICAvLyBUT0RPKGthc3BlcmwpOiBTdHJpY3RlciBjaGVja2luZy4gT25seSBhbGxvdyBpZGVudGlmaWVyc1xuICAgICAgICAvLyBhbmQgc3RyaW5ncyBhcyBrZXlzLiBNYXliZSBhbHNvIGtleXdvcmRzP1xuICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLnBlZWsudmFsdWU7XG4gICAgICAgIGtleXMucHVzaCh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUgOiB0aGlzLnBlZWsudGV4dCk7XG5cbiAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICAgIHRoaXMuZXhwZWN0KCc6Jyk7XG5cbiAgICAgICAgdmFsdWVzLnB1c2godGhpcy5wYXJzZUV4cHJlc3Npb24oKSk7XG4gICAgICB9IHdoaWxlICh0aGlzLm9wdGlvbmFsKCcsJykpO1xuICAgIH1cblxuICAgIHRoaXMuZXhwZWN0KCd9Jyk7XG5cbiAgICByZXR1cm4gbmV3IExpdGVyYWxPYmplY3Qoa2V5cywgdmFsdWVzKTtcbiAgfVxuXG4gIHBhcnNlRXhwcmVzc2lvbkxpc3QodGVybWluYXRvcikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIGlmICh0aGlzLnBlZWsudGV4dCAhPSB0ZXJtaW5hdG9yKSB7XG4gICAgICBkbyB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHRoaXMucGFyc2VFeHByZXNzaW9uKCkpO1xuICAgICAgIH0gd2hpbGUgKHRoaXMub3B0aW9uYWwoJywnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIG9wdGlvbmFsKHRleHQpIHtcbiAgICBpZiAodGhpcy5wZWVrLnRleHQgPT09IHRleHQpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZXhwZWN0KHRleHQpIHtcbiAgICBpZiAodGhpcy5wZWVrLnRleHQgPT09IHRleHQpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVycm9yKGBNaXNzaW5nIGV4cGVjdGVkICR7dGV4dH1gKTtcbiAgICB9XG4gIH1cblxuICBhZHZhbmNlKCl7XG4gICAgdGhpcy5pbmRleCsrO1xuICB9XG5cbiAgZXJyb3IobWVzc2FnZSkge1xuICAgIHZhciBsb2NhdGlvbiA9ICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKVxuICAgICAgICA/IGBhdCBjb2x1bW4gJHt0aGlzLnRva2Vuc1t0aGlzLmluZGV4XS5pbmRleCArIDF9IGluYFxuICAgICAgICA6IGBhdCB0aGUgZW5kIG9mIHRoZSBleHByZXNzaW9uYDtcblxuICAgIHRocm93IG5ldyBFcnJvcihgUGFyc2VyIEVycm9yOiAke21lc3NhZ2V9ICR7bG9jYXRpb259IFske3RoaXMuaW5wdXR9XWApO1xuICB9XG59XG4iXX0=